さて。早速移転して早速重たそうな話題を持ち込んできました。きみのぶです。 このサイトのタイトルにもなっている同期技術。僕は同期というものに並々ならぬ執着を持っています。これが実に面白いのです。まぁ、だからSelf-hosted LiveSyncみたいなプラグインを作っているのですが。 と言う事で、同期技術の話を書いていきますね。最初にネタ出し尽くしたら後で息切れしそう。
同期の種類
さて世の中には同期と呼ばれているものがそこそこありますが、そのうち半分ぐらいのものは、実際には比較と上書きしか行っていなかったりします。まぁ同期と言えば同期なのですが…。 ぷーおんさんの所でも散々語りましたが、同期というのは僕の中では、積み上げた歴史をお互いに交換するような行為だと思ってます。なので、比較するまでもなく、前回交換したところから先を持ち寄って、同時にお互い書き込んじゃった所を各自訂正してさらに持ち寄る、そんな感じですね。 ちなみにSelf-hosted LiveSyncが使っているCouchDBやPouchDBはこの通りに動きます。これはCouchDB使ってたら当たり前の実装なので割愛しますね。今回はこの差分同期の中でも、LiveSyncがやってるトラフィック節約について書いてみます。
LiveSyncがやってるエコ
Self-hosted LiveSyncは、Obsidian上のファイルを一旦Obsidianから勝手に拝借したデータベースに保管しています。その時に、ファイルをメタデータとチャンクというものに分けて保存。チャンクはファイルの内容を都合の良いところで切ったものです。メタデータにはファイル名、変更日、サイズ、そして使用しているチャンクの一覧が保存されています。 だいたいこう言う構造ですね。
graph LR
A.md-->A;
B.md-->B;
C.md-->C;
A-->1["Willy Wonka, Willy Wonka"];
A-->2["The amazing Chocolatier"];
A-->1;
A-->3["Everybody give a cheer!"];
B-->4["Charlie and the Chocolate Factory"];
B-->5[" is a 2005 musical fantasy film"];
C-->6["When I heard `Wonka's welcome song`, so upset."];
C-->7["I'm still afraid this."];
subgraph storage
A.md
B.md
C.md
end
subgraph localDatabase
subgraph metadata
A
B
C
end
subgraph chunks
1
2
3
4
5
6
7
end
end
このチャンクは、mdファイルの場合は改行やheadingなんかで分割され、その中身のハッシュでIDがつけられます。思いついた時はなかなか冴えてると思いました。 で、送る側はこのメタデータとサーバに存在しないチャンクのみをサーバに送信。なので、ファイルを編集してもメタデータと変更された行のチャンクだけが送信されます。例えば
Willy Wonka, Willy Wonka
The amazing Chocolatier
Willy Wonka, Willy Wonka
Everybody give a cheer!
を
Willy Wonka, Willy Wonka
The amazing Chocolatier!
Willy Wonka, Willy Wonka
Everybody give a cheer!
にするとメタデータとThe amazing Chocolatier!だけが送信対象。実にエコですよね。 また、サーバにないものだけを送信するのでThe amazing Chocolatier!と何かで書いたことがあれば再利用されます。実にエコ。ためらい変更し放題です。
同期する際にはサーバと歴史を交換することは前述の通りですが、衝突が無い限りは一番最新の状態だけ転送します。つまりその間のリビジョンで発生した、途中経過は転送されません。 受信時には、最近のバージョンで実装されたRead chunks onlineが有効になっているため、最新のメタデータとそれで使用されているチャンクだけが取得されます。結果として必要最低側のデータ転送で修正が転送される事になります。いやはやすごいですね。
また、End to Endの暗号化は、転送する際に転送するデータだけにオンメモリで実行されます。安全で、そして最低限。工夫しがいがあった所ですね。
そんなこんなで、ここ数バージョンでSelf-hosted LiveSyncはめちゃくちゃ高速化しました。それが原因で、早くなりすぎてIBM CloudantのAPI制限に当たりやすくなってしまい、多少の修正が必要になったりしたぐらい。 まだIssueも落ち着いていないですが、ここはがっつり直して進めていきたいですね。 早く返事書かないと(英語で返信するには体力が……)
こんな感じで、強めの思い入れで同期プラグイン作ってます。何か疑問点とかあったらぜひ教えてください。
2022/10/16 45分。前後半にすべきだったか。